home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / cat / fredprot.i < prev    next >
Text File  |  1997-10-26  |  31KB  |  942 lines

  1. IMPLEMENTATION MODULE FredProtokoll;
  2.  
  3. (*==============================================================*
  4.  * Modul:               Protokollmodul fr Fred                 *
  5.  * Autor:               Johannes G”ttker-Schnetmann             *
  6.  * Autor:               Dirk Steins                             *
  7.  * erstellt am:         Juni 1993                               *
  8.  * letzte Žnderung am:  12.06.1993                              *
  9.  * Version:             1.0                                     *
  10.  * Interne Version:     V#0002                                  *
  11.  *==============================================================*
  12.  
  13.  Dieses Modul macht Fred zu einem Xacc-Hauptprogramm der Stufe 1. Aužerdem 
  14.  werden vom AV/VA-Protokoll die sinnvollen Msgs untersttzt.
  15.  
  16.  Entstanden ist dieses Modul aus dem Protokoll-Modul von CAT.
  17.  
  18.  Die Erl„uterung des erweiterten Protokolls steht weiter unten. "HelloWatchDog"
  19.  hat jetzt die allgemeinere Bedeutung "CatMsg".
  20.  Insbesondere die Erkennung des WatchDogs soll in einer der n„chsten Versionen
  21.  nach M”glichkeit auf die Methode des erweiterten Protokolls umgestellt werden.
  22.  
  23.  *----------------------------------------------------------------------------
  24.  * Datum    Vers. Autor  Žnderung (Arbeitsbericht)                            
  25.  *----------------------------------------------------------------------------
  26.  * 01.02.92 0002  JGS    Protokollerweiterung fr Steueraccs
  27.  * 24.05.93 0003  DS     Erweiterung um MultiTasking-Untersttzung
  28.  *                       CAT XACC-Versionsnummer ge„ndert auf 20H
  29.  *----------------------------------------------------------------------------
  30.  *)
  31.  
  32. FROM SYSTEM          IMPORT ADR, ADDRESS, WORD, CADR, CALLSYS, TSIZE;
  33. FROM WdwManager      IMPORT NewWindowIsTop, WindowIsClosed;
  34. FROM Void            IMPORT v;
  35. FROM CatTypes        IMPORT Str255Ptr, String255;
  36. FROM CatGlobal       IMPORT multiTask, multiTOS, magIx, magIxVer;
  37. FROM Storage         IMPORT ALLOCATE;
  38. IMPORT BinOps;
  39. IMPORT FileNames;
  40.  
  41. IMPORT MagicAES;
  42. IMPORT MagicStrings;
  43. IMPORT mtAppl;
  44. IMPORT mtAlerts;
  45. IMPORT MagicDOS;
  46. IMPORT MagicCookie;
  47. IMPORT mtCommand;
  48.  
  49. FROM SEProto IMPORT tShellSet, tEditSet, tEditCommands, tShellCommands;
  50. IMPORT SEProto;
  51.  
  52. CONST
  53.  
  54.   appName    = 'FRED    '+0C+'XDSC'+0C+'1Texteditor'+0C+'2ED'+0C+0C;
  55.   
  56.   supportedSEProtoVersion = 0100H;
  57.   
  58.  
  59. (* XAcc: *)
  60.  
  61.   ACC_ID    = 400H;
  62.   ACC_OPEN  = 401H;
  63.   ACC_CLOSE = 402H;
  64.   ACC_ACC   = 403H;
  65.   ACC_EXIT  = 404H;
  66.   ACC_ACK   = 500H;
  67.   ACC_TEXT  = 501H;
  68.   ACC_KEY   = 502H;
  69.   
  70. (* PC-Help Protokoll *)
  71.   AC_HELP   = 1025;         (* message to DA *)
  72.   AC_REPLY  = 1026;         (* message from DA *)
  73.   AC_VERSION= 1027;         (* Ask DA for version *)
  74.   AC_COPY   = 1028;         (* Ask DA to copy screen to clipboard *)
  75.  
  76. (* AV/VA-Protokoll *)
  77.  
  78.   AV_PROTOKOLL     = 4700H;
  79.   VA_PROTOSTATUS   = 4701H;
  80.  
  81. (* not used *)
  82.   AV_GETSTATUS     = 4703H;
  83.   AV_STATUS        = 4704H;
  84.   VA_SETSTATUS     = 4705H;
  85. (*----------*)
  86.  
  87.   AV_SENDKEY       = 4710H;
  88.  
  89. (* not used *)
  90.   VA_START         = 4711H;
  91.   AV_ASKFILEFONT   = 4712H;
  92.   VA_FILEFONT      = 4713H;
  93.   AV_ASKCONFONT    = 4714H;
  94.   VA_CONFONT       = 4715H;
  95.   AV_ASKOBJECT     = 4716H;
  96.   VA_OBJECT        = 4717H;
  97.   AV_OPENCONSOLE   = 4718H;
  98.   VA_CONSOLEOPEN   = 4719H;
  99. (*----------*)
  100.  
  101.   AV_OPENWIND      = 4720H;
  102.   VA_WINDOPEN      = 4721H;
  103.   AV_STARTPROG     = 4722H;
  104.   VA_PROGSTART     = 4723H;
  105.   AV_ACCWINDOPEN   = 4724H;
  106.  
  107. (* not used *)
  108.   VA_DRAGACCWIND   = 4725H; (* NOCH, wichtig fr Kommandozeile an Takeoff *)
  109. (*----------*)
  110.  
  111.   AV_ACCWINDCLOSED = 4726H;
  112.   AV_PATH_UPDATE   = 4730H;
  113.  
  114. (* Bits *)
  115.  
  116.   xAV_SENDKEY       = 0;
  117.   xAV_ASKFILEFONT   = 1;
  118.   xAV_ASKCONFONT    = 2; (* auch xAV_OPENCONSOLE *)
  119.   xAV_ASKOBJECT     = 3;
  120.   xAV_OPENWIND      = 4;
  121.   xAV_STARTPROG     = 5;
  122.   xAV_ACCWINDOPEN   = 6; (* auch xAV_ACCWINDCLOSED *)
  123.   xAV_STATUS        = 7; (* auch AV_GETSTATUS *)
  124.  
  125.  
  126. (* Um sich alle installierten Accs beim XAcc-Protokoll zu merken wird hier ein *) 
  127. (* kleines Array angelegt. Das ist natrlich statisch, aber darber wrde ich  *)
  128. (* mir erstmal noch keine Sorgen machen.. :-)                                  *)
  129.  
  130. CONST maxAcc = 40;      (* Wegen MTOS von 6 auf 40 erweitert. Zwar kann 
  131.                          * man unter MTOS auch mehr als 40 ACCs und Applikationen 
  132.                          * haben, aber das w„re ziemlich krank *)
  133.  
  134. CONST maxBufLen = 128;  (* L„nge des statischen Textbuffers *)
  135.  
  136.       memDescrSize  = 2048; (* 1 kB globaler Speicher *)
  137.  
  138. TYPE        (* for systems with memory protection (MultiTOS) *)
  139.         memDescr        = RECORD
  140.                             CASE : BOOLEAN OF
  141.                             TRUE:
  142.                               apName  : ARRAY [0..49] OF CHAR; (* our extended application name *)
  143.                               textBuf : ARRAY [0..maxBufLen-1] OF CHAR;
  144.                               mPath   : String255;
  145.                               mName   : String255; 
  146.                               mRec    : SEProto.tMessRec; |
  147.                             FALSE:
  148.                               allInOne: ARRAY [0..memDescrSize-1] OF CHAR;
  149.                             END;
  150.                           END;
  151.  
  152. TYPE sePartner  = RECORD
  153.                     apId    : INTEGER;
  154.                     protoVersion: CARDINAL;
  155.                     shell   : tShellSet;
  156.                     editor  : tEditSet;
  157.                   END;
  158.  
  159. CONST   maxSe   = 3;
  160.  
  161. VAR accCount : CARDINAL;
  162.     acc      : ARRAY[1..maxAcc] OF INTEGER;
  163.     messBuff : ARRAY [0..31] OF INTEGER;    (* Platz fr Messagebuffer *)
  164.     startApId: INTEGER;     (* Von wem kam die letzte AV_STARTPROG *)
  165.     memPtr   : POINTER TO memDescr;         (* global buffer *)
  166.     seList   : ARRAY [1..maxSe] OF sePartner;
  167.     seCount  : INTEGER;
  168.  
  169.  
  170. PROCEDURE send(msg : CARDINAL; dest : INTEGER; REF data : ARRAY OF WORD);
  171. (* Anpassen, damit man damit demn„chst l„ngere Msgs verschicken kann *)
  172. VAR mess : POINTER TO RECORD
  173.              msg : CARDINAL;
  174.              id  : INTEGER;
  175.              overLength : INTEGER;
  176.              w : ARRAY[0..4] OF WORD
  177.            END;
  178.    z : CARDINAL;
  179. BEGIN
  180.   mess := ADR(messBuff);
  181.   FOR z := 0 TO 4 DO mess^.w[z] := data[z] END;
  182.   mess^.msg := msg;
  183.   mess^.id  := mtAppl.ApplIdent;
  184.   mess^.overLength := 0;
  185.   MagicAES.ApplWrite(dest, 16, mess^);
  186.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  187.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  188. END send;
  189.  
  190. PROCEDURE SendMess(msg : CARDINAL; catType : INTEGER; l : LONGCARD; i2, i3, dest : INTEGER);
  191. VAR data : RECORD catType : INTEGER; l : LONGCARD; i2, i3 : INTEGER END;
  192. BEGIN
  193.   data.catType := catType; data.l := l; data.i2 := i2; data.i3 := i3;
  194.   send(msg, dest, data);
  195. END SendMess;
  196.  
  197. PROCEDURE SendMessInt(msg : CARDINAL; catType, i1, i2, i3, i4, dest : INTEGER);
  198. VAR data : RECORD catType, i1, i2, i3, i4 : INTEGER END;
  199. BEGIN
  200.   data.catType := catType; data.i1 := i1; data.i2 := i2; data.i3 := i3; data.i4 := i4;
  201.   send(msg, dest, data);
  202. END SendMessInt;
  203.  
  204. PROCEDURE SendAdr(msg : CARDINAL; catType, i1 : INTEGER; l : LONGCARD; i2, dest : INTEGER);
  205. VAR data : RECORD catType : INTEGER; i1 : INTEGER; l : LONGCARD; i2 : INTEGER END;
  206. BEGIN
  207.   data.catType := catType; data.i1 := i1; data.l := l; data.i2 := i2;
  208.   send(msg, dest, data);
  209. END SendAdr;
  210.  
  211. PROCEDURE SendTerminate();
  212. (* Nachricht an den WatchDog schicken, daž Cat beendet wurde *)
  213.   VAR m : POINTER TO RECORD
  214.             messId : CARDINAL;
  215.             apId   : INTEGER;
  216.             over   : INTEGER;
  217.             r      : ARRAY[3..7] OF INTEGER;
  218.           END;
  219.       i : CARDINAL;
  220.       mess: SEProto.tPtrMessRec;
  221. BEGIN
  222.   (* Und unter MultiTOS auch noch ACC_EXIT verschicken an alle 
  223.    * anderen Applikationen, die sich gemeldet haben
  224.    *)
  225.   IF multiTask
  226.   THEN
  227.     m := ADR(messBuff);
  228.     WITH m^ DO
  229.       messId := ACC_EXIT;
  230.       apId   := mtAppl.ApplIdent;
  231.       over   := 0;
  232.     END;
  233.     FOR i := 1 TO accCount - 1 DO
  234.       MagicAES.ApplWrite(acc[i], 16, m^);
  235.       MagicAES.WindUpdate(MagicAES.ENDUPDATE);
  236.       MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  237.     END;
  238.     (* Jetzt an alle SE-Applikationen noch ein ES_QUIT schicken *)
  239.     mess := ADR(messBuff);
  240.     WITH mess^ DO
  241.       msg := SEProto.ES_QUIT;
  242.       apId := mtAppl.ApplIdent;
  243.       overLen := 0;
  244.       FOR i := 0 TO 4 DO
  245.         data[i] := 0;
  246.       END;
  247.     END;
  248.     i := 1; 
  249.     WHILE i <= CARDINAL(seCount) DO
  250.       MagicAES.ApplWrite(seList[i].apId, 16, mess^);
  251.       MagicAES.WindUpdate(MagicAES.ENDUPDATE);
  252.       MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  253.       INC (i);
  254.     END;
  255.   ELSE
  256.     accCount := 1;
  257.   END;
  258. END SendTerminate;
  259.  
  260. PROCEDURE SendProgstart(error : BOOLEAN);
  261. (* dem Acc mitteilen, ob der Programmstart geklappt hat, not yet implementet *)
  262.   VAR val : INTEGER;
  263. BEGIN
  264.   IF error THEN val := 0 ELSE val := 1 END;
  265.   SendMess(VA_PROGSTART, val, 0,0,0, startApId);
  266. END SendProgstart;
  267.  
  268. PROCEDURE SendAcknowledge (apId : INTEGER; succ: BOOLEAN);
  269.   VAR val : INTEGER;
  270. BEGIN
  271.   IF succ THEN val := 1 ELSE val := 0 END;
  272.   SendMess (ACC_ACK, val, 0,0,0, apId);
  273. END SendAcknowledge;
  274.  
  275. PROCEDURE SendVaWindopen (apId : INTEGER; error : BOOLEAN);
  276. (* Das ist unbenutzt, ist wohl auch nur in Gemini sinnvoll *)
  277. BEGIN
  278.   IF error 
  279.   THEN
  280.     SendMess(VA_WINDOPEN, 0, 0,0,0, apId);
  281.   ELSE
  282.     SendMess(VA_WINDOPEN, 1, 0,0,0, apId);
  283.   END;
  284. END SendVaWindopen;
  285.  
  286. PROCEDURE SendOpenwind (id : INTEGER; path, name : ADDRESS);
  287. (* einer anderen Applikation sagen, das sie ein Fenster ”ffnen soll
  288.  * ist fr den Fall, das CAT oder Eddix schon ge”ffnet sind, dann wird 
  289.  * diese Message verschickt.
  290.  *)
  291.   VAR mess : POINTER TO RECORD
  292.                messId : INTEGER;
  293.                apId   : INTEGER;
  294.                over   : INTEGER;
  295.                fPath              : ADDRESS;
  296.                fName              : ADDRESS;
  297.                e15                : INTEGER;
  298.              END;
  299.      fPtr  : Str255Ptr;
  300. BEGIN
  301.   mess := ADR (messBuff);
  302.   (* Filenamen und Pfad kopieren *)
  303.   fPtr := path;
  304.   MagicStrings.Assign (fPtr^, memPtr^.mPath);
  305.   fPtr := name;
  306.   MagicStrings.Assign (fPtr^, memPtr^.mName);
  307.   WITH mess^ DO
  308.     messId := AV_OPENWIND;
  309.     apId   := mtAppl.ApplIdent;
  310.     over   := 0;
  311.     fPath  := ADR (memPtr^.mPath);
  312.     fName  := ADR (memPtr^.mName);
  313.     e15    := 0;
  314.   END;
  315.   MagicAES.ApplWrite(id, 16, mess^);
  316.   MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Um es auch mal abzuschicken.. *)
  317.   MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  318. END SendOpenwind;
  319.  
  320. PROCEDURE SendHelp (VAR str : ARRAY OF CHAR);
  321.   (* Request Help via PC_HELP Protokoll *)
  322.   VAR accId : INTEGER;
  323.       mess  : POINTER TO RECORD
  324.                messId : INTEGER;
  325.                apId   : INTEGER;
  326.                over   : INTEGER;
  327.                data   : ADDRESS;
  328.                fName  : ADDRESS;
  329.                e15    : INTEGER;
  330.              END;
  331.      helpApp: ARRAY [0..9] OF CHAR; 
  332.      i      : INTEGER;
  333. BEGIN
  334.   mess := ADR(messBuff);
  335.   (* String kopieren in statischen Buffer (igitt) *)
  336.   i := 0;
  337.   WHILE (i < maxBufLen-1) & (str[i] # 0C) DO
  338.     memPtr^.textBuf[i] := str[i];
  339.     INC (i);
  340.   END;
  341.   memPtr^.textBuf [i] := 0C;
  342.   (* Search for PC/TC-HELP Accessory *)
  343.   MagicStrings.Assign ('ST-GUIDE', helpApp);
  344.   accId := MagicStrings.Length (helpApp);
  345.   (* Extend name with Spaces *)
  346.   WHILE accId < 8 DO 
  347.     helpApp[accId] := ' '; 
  348.     helpApp[accId+1] := ''; 
  349.     INC (accId);
  350.   END;
  351.   accId := MagicAES.ApplFind (ADR(helpApp));
  352.   IF accId >= 0
  353.   THEN
  354.     WITH mess^ DO
  355.       messId := AC_HELP;
  356.       apId   := mtAppl.ApplIdent;
  357.       over   := 0;
  358.       data   := ADR(memPtr^.textBuf);
  359.     END;
  360.     MagicAES.ApplWrite (accId, 16, mess^);
  361.   END;
  362. END SendHelp;
  363.  
  364. PROCEDURE SendSeAcknowledge (apId: INTEGER; res: BOOLEAN);
  365.   VAR mess  : SEProto.tPtrMessRec;
  366.       i     : INTEGER;
  367. BEGIN
  368.   mess := ADR (messBuff);
  369.   WITH mess^ DO
  370.     msg := SEProto.ES_ACK;
  371.     apId  := mtAppl.ApplIdent;
  372.     overLen := 0;
  373.     FOR i := 0 TO 4 DO data[i] := 0 END;
  374.     acknowledge := res;
  375.   END;
  376.   MagicAES.ApplWrite (apId, 16, mess^);
  377. END SendSeAcknowledge;
  378.  
  379. PROCEDURE SendEsMessage (messNum: INTEGER; adr: ADDRESS);
  380.   VAR mess  : SEProto.tPtrMessRec;
  381.       fPtr  : Str255Ptr;
  382.       i     : INTEGER;
  383. BEGIN
  384.   IF seCount < 1 THEN RETURN END;
  385.   mess := ADR (messBuff);
  386.   fPtr := adr;
  387.   IF fPtr # NIL
  388.   THEN
  389.     MagicStrings.Assign (fPtr^, memPtr^.mPath);
  390.     fPtr := ADR(memPtr^.mPath);
  391.   END;
  392.   IF ~(tEditCommands(messNum-SEProto.ES_INIT) IN seList[1].editor)
  393.   THEN RETURN END;
  394.   WITH mess^ DO
  395.     msg := messNum;
  396.     apId  := mtAppl.ApplIdent;
  397.     overLen := 0;
  398.     FOR i := 0 TO 4 DO data[i] := 0 END;
  399.     filePtr := ADDRESS(fPtr);
  400.   END;
  401.   MagicAES.ApplWrite (seList[1].apId, 16, mess^);
  402. END SendEsMessage;
  403.  
  404. PROCEDURE InitSeProto (adr: ADDRESS);
  405.   VAR mess : SEProto.tPtrMessRec;
  406.       newMess: SEProto.tPtrMessRec;
  407.       i     : INTEGER;
  408. BEGIN
  409.   mess := adr;
  410.   newMess := ADR (messBuff);
  411.   (* Eintragen in SeProtoliste *)
  412.   WITH newMess^ DO
  413.     msg := SEProto.ES_OK;
  414.     apId  := mtAppl.ApplIdent;
  415.     overLen := 0;
  416.     FOR i := 0 TO 4 DO data[i] := 0 END;
  417.     okShellBits := tShellSet {seInit, seOk, seAck, seOpen, seError, seErrfile, seQuit,
  418.                     seTerminate, seClose};
  419.     okEditBits  := tEditSet {esInit, esOk, esAck, esCompile, esMake, esMakeall, 
  420.                     esLink, esExec, esMakeexec, esQuit};
  421.     okVersion   := supportedSEProtoVersion;
  422.     otherId := mess^.apId;
  423.   END;
  424.   (* Antwort zusammenbasteln *)
  425.   IF seCount < maxSe 
  426.   THEN
  427.     INC (seCount);
  428.     WITH seList[seCount] DO
  429.       apId := mess^.apId;
  430.       (* Minimale Daten erstellen *)
  431.       protoVersion := BinOps.LowerCard (supportedSEProtoVersion, mess^.version);
  432.       shell := mess^.shellBits * newMess^.okShellBits;
  433.       editor := mess^.editBits * newMess^.okEditBits;
  434.     END;
  435.   END;
  436.   (* Jetzt Antwort schicken *)
  437.   MagicAES.ApplWrite (mess^.apId, 16, newMess^);
  438. END InitSeProto;
  439.  
  440. PROCEDURE ActivateSeProto (adr: ADDRESS);
  441.   VAR mess : SEProto.tPtrMessRec;
  442. BEGIN
  443.   mess := adr;
  444.   IF mess^.otherId # mtAppl.ApplIdent THEN RETURN END;
  445.   (* Eintragen in Liste *)
  446.   IF seCount < maxSe 
  447.   THEN
  448.     INC (seCount);
  449.     WITH seList[seCount] DO
  450.       apId := mess^.apId;
  451.       (* Minimale Daten erstellen *)
  452.       protoVersion := BinOps.LowerCard (supportedSEProtoVersion, mess^.okVersion);
  453.       shell := mess^.okShellBits * tShellSet {seInit, seOk, seAck, seOpen, seError, seErrfile, seQuit,
  454.                     seTerminate, seClose};
  455.       editor := mess^.okEditBits * tEditSet {esInit, esOk, esAck, esCompile, esMake, esMakeall, 
  456.                     esLink, esExec, esMakeexec, esQuit};
  457.     END;
  458.   END;
  459. END ActivateSeProto;
  460.  
  461. PROCEDURE RemoveSeProto (apId : INTEGER);
  462.   VAR i : INTEGER;
  463. BEGIN
  464.   i := 1;
  465.   WHILE (i <= seCount) & (seList[i].apId # apId) DO INC (i) END;
  466.   IF (i <= seCount) & (i <= maxSe) THEN
  467.     FOR i := i+1 TO seCount DO
  468.       acc[i-1] := acc[i];
  469.     END;
  470.     DEC (seCount);
  471.   END;
  472. END RemoveSeProto;
  473.  
  474. PROCEDURE IsProtokoll(mess : ADDRESS;
  475.                      VAR kReturn : INTEGER; VAR mokState : BITSET;
  476.                      VAR pName, pCmd : Str255Ptr):React;
  477.  
  478.   PROCEDURE accInit(mess : ADDRESS);
  479.   (* XAcc-Protokoll, accInit behandeln *)
  480.   VAR i : CARDINAL;
  481.       access : POINTER TO RECORD
  482.                  messId : INTEGER;
  483.                  apId   : INTEGER;
  484.                  over   : INTEGER;
  485.                  version, protoStep : CHAR;
  486.                  name               : Str255Ptr;
  487.                  menuId             : INTEGER;
  488.                  accId              : INTEGER
  489.                END;
  490.     PROCEDURE checkId (id : INTEGER): BOOLEAN;
  491.     (* Prft, ob schon ein Prozess mit der ID registriert ist *)
  492.       VAR i : CARDINAL;
  493.     BEGIN
  494.       FOR i := 1 TO accCount - 1 DO 
  495.         IF acc[i] = id THEN RETURN FALSE END;
  496.       END;
  497.       RETURN TRUE;
  498.     END checkId;
  499.     
  500.   BEGIN
  501.     access := mess;
  502.     IF multiTask
  503.     THEN
  504.       IF (accCount < maxAcc) & checkId (access^.apId)
  505.       THEN
  506.         acc[accCount]     := access^.apId; (* ID des Acc, das sich gerade anmeldet *)
  507.         access^.messId    := ACC_ACC;
  508.         access^.apId      := mtAppl.ApplIdent;
  509.         access^.version   := CHR(20H);
  510.         access^.protoStep := 1C;
  511.         access^.name      := ADR(memPtr^.apName);
  512.         access^.menuId    := 0;
  513.         access^.accId     := 0;
  514.  
  515.         MagicAES.ApplWrite(acc[accCount], 16, access^);
  516.         MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  517.         MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  518.         INC(accCount);
  519.       END;
  520.     ELSE (* not MultiTOS *)
  521.       IF (accCount < maxAcc) & checkId (access^.apId) THEN
  522.   
  523.         acc[accCount]     := access^.apId; (* ID des Acc, das sich gerade anmeldet *)
  524.         access^.messId    := ACC_ACC;
  525.         access^.accId     := access^.apId;
  526.         access^.apId      := mtAppl.ApplIdent;
  527.         access^.over      := 0;
  528.         (* Die anderen Daten stimmen zu diesem Zeitpunkt schon.. *)
  529.   
  530.         FOR i := 1 TO accCount-1 DO
  531.           MagicAES.ApplWrite(acc[i], 16, access^);
  532.           MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  533.           MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  534.         END; (* Alle anderen Accs benachrichtigen *)
  535.                                    
  536.         access^.messId    := ACC_ID;
  537.         access^.version   := CHR(20H);
  538.         access^.protoStep := 1C;
  539.         access^.name      := ADR(memPtr^.apName);
  540.         access^.menuId    := 0;
  541.         access^.accId     := 0;
  542.   
  543.         MagicAES.ApplWrite(acc[accCount], 16, access^);
  544.         INC(accCount);
  545.   
  546.         MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  547.         MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  548.       END; 
  549.     END;
  550.   END accInit;
  551.  
  552.   PROCEDURE SendVaProtostatus(mess : ADDRESS);
  553.   VAR id : INTEGER;
  554.       access : POINTER TO RECORD
  555.                  messId : INTEGER;
  556.                  apId   : INTEGER;
  557.                  over   : INTEGER;
  558.                  b21, b22, b23      : BITSET;
  559.                  prgName            : ADDRESS;
  560.                END;
  561.   BEGIN
  562.     access := mess;
  563.     id             := access^.apId;
  564.     access^.messId := VA_PROTOSTATUS;
  565.     access^.apId   := mtAppl.ApplIdent;
  566.     access^.over   := 0;
  567.     access^.b21    := {xAV_SENDKEY, xAV_ACCWINDOPEN, xAV_OPENWIND};
  568.     access^.b22    := {};
  569.     access^.b23    := {};
  570.     access^.prgName:= ADR(memPtr^.apName);
  571.     MagicAES.ApplWrite(id, 16, access^);
  572.     MagicAES.WindUpdate(MagicAES.ENDUPDATE); (* Abschicken *)
  573.     MagicAES.WindUpdate(MagicAES.BEGUPDATE);
  574.   END SendVaProtostatus;
  575.   
  576.   PROCEDURE RemoveAcc (apId : INTEGER);
  577.     VAR i : CARDINAL;
  578.   BEGIN
  579.     i := 1;
  580.     WHILE (i < accCount) & (acc[i] # apId) DO INC (i) END;
  581.     IF i < accCount THEN
  582.       FOR i := i TO accCount - 2 DO
  583.         acc[i] := acc[i+1];
  584.       END;
  585.       DEC (accCount);
  586.     END;
  587.   END RemoveAcc;
  588.  
  589. VAR access : POINTER TO RECORD
  590.                messId : INTEGER;
  591.                apId   : INTEGER;
  592.                over   : INTEGER;
  593.                CASE :CARDINAL OF
  594.                (* AV_SENDKEY *)
  595.                  1 : mokState       : INTEGER;
  596.                      kReturn        : INTEGER;
  597.                      e11, e12, e13  : INTEGER|
  598.                (* AV_STARTPROG *)
  599.                  2 : pName, pCmd    : ADDRESS;
  600.                      e14            : INTEGER|
  601.                (* AV_OPENWIND  *)
  602.                  3 : fPath          : ADDRESS;
  603.                      fName          : ADDRESS;
  604.                      e15            : INTEGER |
  605.                  4 : i              : ARRAY[0..4] OF INTEGER|
  606.                  5 : e16            : INTEGER;
  607.                      text           : ADDRESS; |
  608.                END;
  609.              END;
  610.  
  611. (* TYPE React        = (rNoproto, rNone, rChar, rText); *)
  612. BEGIN
  613.   access := mess;
  614.   (* Zun„chst einmal die Initialisierungsmsgs fr XAcc und VA *)
  615.   CASE access^.messId OF
  616.     ACC_ID      : accInit(mess); |     (* Xacc-Protokoll behandeln *)
  617.   (* AccOpen und AccClose werden einfach berh”rt! *)
  618.     ACC_ACC     : RETURN rNone; |
  619.     ACC_EXIT    : (* XACC Acc_Exit *)
  620.                   (* remove Accessorie from acc list *)
  621.                   RemoveAcc (access^.apId); |
  622.     ACC_KEY     : (* Tastendruck durchreichen *)
  623.                   (* Genau umgedreht zu AV_SENDKEY *)
  624.                   kReturn := access^.mokState;
  625.                   mokState:= BITSET(access^.kReturn);
  626.                   SendAcknowledge (access^.apId, TRUE);
  627.                   RETURN rChar; |
  628.     ACC_TEXT    : (* get text via XACC *)
  629.                   kReturn := access^.apId;    (* apId merken fr Acknowledge *)
  630.                   pName   := access^.text;    (* Pointer auf Text *)
  631.                   RETURN rText; |
  632.   ELSE
  633.   END;
  634.   CASE access^.messId OF
  635.     AV_PROTOKOLL: (* hier behandelt, WatchDog suchen *)
  636.                   SendVaProtostatus(mess); |  (* .. und dem Acc sagen, was wir k”nnen *)
  637.     (* AV-Msgs, die direkt hier behandelt werden *)
  638.     AV_SENDKEY  : (* Tastendruck durchreichen *)
  639.                   kReturn := access^.kReturn;
  640.                   mokState:= BITSET(access^.mokState);
  641.                   RETURN rChar; |
  642.     AV_ACCWINDOPEN: (* AccFenster auf -> rein in die Queue *)
  643.                   NewWindowIsTop(access^.i[0], access^.apId); |
  644.     AV_ACCWINDCLOSED:  (* AccFenster zu -> raus aus der Queue *)
  645.                   WindowIsClosed(access^.i[0]); |
  646.     AV_STARTPROG: (* Acc sagt: Folgendes Programm starten! *)
  647.                   pName := access^.pName; pCmd := access^.pCmd;
  648.                   startApId := access^.apId;
  649.                   RETURN rStart; |
  650.     AV_OPENWIND:  (* Woasn doas? *)
  651.                   pName := access^.fPath; pCmd := access^.fName;
  652.                   SendVaWindopen(access^.apId, FALSE);
  653.                   RETURN rOpen; |
  654.     VA_START:     (* Unter Mag!X: Neue Dokumente auf CAT gezogen oder so *)
  655.                   pName := NIL; pCmd := access^.fPath;
  656.                   (* Best„tigung gibt es keine *)
  657.                   RETURN rOpen; |
  658.   ELSE
  659.   END;
  660.   CASE access^.messId OF
  661.     SEProto.SE_INIT: InitSeProto (access); |
  662.     SEProto.SE_OK:   ActivateSeProto (access); |
  663.     SEProto.SE_ACK:  (* Nichts weiter machen *) |
  664.     SEProto.SE_OPEN:      
  665.                   (* Analog zu VA_START behandeln *)
  666.                   pName := NIL; pCmd := access^.fPath;
  667.                   startApId := access^.apId;
  668.                   SendSeAcknowledge (access^.apId, TRUE);
  669.                   RETURN rOpen; |
  670.     SEProto.SE_ERROR,
  671.     SEProto.SE_ERRFILE,
  672.     SEProto.SE_TERMINATE,
  673.     SEProto.SE_CLOSE:     
  674.                   (* Einfach Pointer auf Messagebuffer zurckgeben
  675.                    *)
  676.                   pCmd := ADDRESS(access);
  677.                   SendSeAcknowledge (access^.apId, TRUE); 
  678.                   RETURN rSeMess; |
  679.     SEProto.SE_QUIT:      
  680.                   RemoveSeProto (access^.apId); |
  681.   ELSE
  682.   END;
  683.   RETURN rNoproto;
  684.  
  685. (*
  686.   IF    access^.messId = ACC_ID   THEN             (* hier behandelt, WatchDog suchen *)
  687.     accInit(mess);      (* Xacc-Protokoll behandeln *)
  688.     RETURN rNone;
  689.   (* AccOpen und AccClose werden einfach berh”rt! *)
  690.   ELSIF (access^.messId = ACC_ACC) & multiTask THEN  (* hier behandelt, WatchDog suchen *)
  691.     RETURN rNone;
  692.   (* AccOpen und AccClose werden einfach berh”rt! *)
  693.   ELSIF access^.messId = AV_PROTOKOLL THEN         (* hier behandelt, WatchDog suchen *)
  694.     SendVaProtostatus(mess);                  (* .. und dem Acc sagen, was wir k”nnen *)
  695.     RETURN rNone;
  696.   
  697.   ELSIF access^.messId = ACC_EXIT THEN                    (* XACC Acc_Exit *)
  698.     (* remove Accessorie from acc list *)
  699.     RemoveAcc (access^.apId);
  700.     RETURN rNone;
  701.   ELSIF access^.messId = ACC_KEY THEN                     (* Tastendruck durchreichen *)
  702.     (* Genau umgedreht zu AV_SENDKEY *)
  703.     kReturn := access^.mokState;
  704.     mokState:= BITSET(access^.kReturn);
  705.     SendAcknowledge (access^.apId, TRUE);
  706.     RETURN rChar;
  707.   ELSIF access^.messId = ACC_TEXT THEN
  708.     (* get text via XACC *)
  709.     kReturn := access^.apId;    (* apId merken fr Acknowledge *)
  710.     pName   := access^.text;    (* Pointer auf Text *)
  711.     RETURN rText;
  712.     
  713.   (* AV-Msgs, die direkt hier behandelt werden *)
  714.   ELSIF access^.messId = AV_SENDKEY   THEN                (* Tastendruck durchreichen *)
  715.     kReturn := access^.kReturn;
  716.     mokState:= BITSET(access^.mokState);
  717.     RETURN rChar;
  718.   ELSIF access^.messId = AV_ACCWINDOPEN  THEN  (* AccFenster auf -> rein in die Queue *)
  719.     NewWindowIsTop(access^.i[0], access^.apId);
  720.     RETURN rNone;
  721.   ELSIF access^.messId = AV_ACCWINDCLOSED THEN (* AccFenster zu -> raus aus der Queue *)
  722.     WindowIsClosed(access^.i[0]);
  723.     RETURN rNone;
  724.   ELSIF access^.messId = AV_STARTPROG THEN   (* Acc sagt: Folgendes Programm starten! *)
  725.     pName := access^.pName; pCmd := access^.pCmd;
  726.     startApId := access^.apId;
  727.     RETURN rStart;
  728.   ELSIF access^.messId = AV_OPENWIND THEN                              (* Woasn doas? *)
  729.     pName := access^.fPath; pCmd := access^.fName;
  730.     SendVaWindopen(access^.apId, FALSE);
  731.     RETURN rOpen;
  732.   ELSIF access^.messId = VA_START THEN
  733.     (* Unter Mag!X: Neue Dokumente auf CAT gezogen oder so *)
  734.     pName := NIL; pCmd := access^.fPath;
  735.     (* Best„tigung gibt es keine *)
  736.     RETURN rOpen;
  737.   ELSE (* Kein bekanntes Protokoll *)
  738.     RETURN rNoproto;
  739.   END;
  740. *)
  741. END IsProtokoll;
  742.  
  743. PROCEDURE ProtoInit ();
  744. (* XACC-Initialisierung unter MTOS *)
  745.   VAR i : INTEGER;
  746.       access : POINTER TO RECORD
  747.                  messId : INTEGER;
  748.                  apId   : INTEGER;
  749.                  over   : INTEGER;
  750.                  version, protoStep : CHAR;
  751.                  name               : Str255Ptr;
  752.                  menuId             : INTEGER;
  753.                  accId              : INTEGER
  754.                END;
  755.      apName : String255;
  756.      apMode,
  757.      apType,
  758.      apId   : INTEGER;
  759. BEGIN
  760.   access := ADR(messBuff);
  761.   access^.messId    := ACC_ID;
  762.   access^.apId      := mtAppl.ApplIdent;
  763.   access^.version   := CHR(20H);
  764.   access^.protoStep := 1C;
  765.   access^.name      := ADR(memPtr^.apName);
  766.   access^.menuId    := 0;
  767.   access^.accId     := 0;
  768.   IF multiTOS OR (magIx & (magIxVer >= $200))
  769.   THEN
  770.     apMode := MagicAES.APFIRST;
  771.     WHILE MagicAES.ApplSearch (apMode, apName, apType, apId) DO
  772.       apMode := MagicAES.APNEXT;
  773.       IF (apType # 1) & (apId # mtAppl.ApplIdent)
  774.       THEN
  775.         MagicAES.ApplWrite(apId, 16, access^);
  776.       END;
  777.     END;
  778.   ELSIF magIx & (magIxVer < $200)
  779.   THEN
  780.     FOR i := 0 TO MagicAES.AESGlobal.apCount - 1 DO
  781.       apName[0] := '?';
  782.       apName[1] := 0C;
  783.       apName[2] := CHR(i);
  784.       apName[3] := 0C;
  785.       apId := MagicAES.ApplFind (ADR(apName));
  786.       IF (apId # 0) & (apId # mtAppl.ApplIdent)
  787.       THEN 
  788.         MagicAES.ApplWrite(apId, 16, access^);
  789.       END;
  790.     END;
  791.   END;
  792. END ProtoInit;
  793.  
  794. PROCEDURE SeProtoInit ();
  795. (* SE-Protokoll Initialisierung unter MTOS *)
  796.   VAR i : INTEGER;
  797.       access : SEProto.tPtrMessRec;
  798.       apName : String255;
  799.       apMode,
  800.       apType,
  801.       apId   : INTEGER;
  802. BEGIN
  803.   access := ADR(messBuff);
  804.   access^.msg       := SEProto.ES_INIT;
  805.   access^.apId      := mtAppl.ApplIdent;
  806.   access^.overLen   := 0;
  807.   access^.shellBits := tShellSet {seInit, seOk, seAck, seOpen, seError, seErrfile, seQuit,
  808.                                seTerminate, seClose};
  809.   access^.editBits  := tEditSet {esInit, esOk, esAck, esCompile, esMake, esMakeall, 
  810.                                    esLink, esExec, esMakeexec, esQuit};
  811.   access^.version   := supportedSEProtoVersion;
  812.  
  813.   IF multiTOS OR (magIx & (magIxVer >= $200))
  814.   THEN
  815.     apMode := MagicAES.APFIRST;
  816.     WHILE MagicAES.ApplSearch (apMode, apName, apType, apId) DO
  817.       apMode := MagicAES.APNEXT;
  818.       IF (apType # 1) & (apId # mtAppl.ApplIdent)
  819.       THEN
  820.         MagicAES.ApplWrite(apId, 16, access^);
  821.       END;
  822.     END;
  823.   ELSIF magIx & (magIxVer < $200)
  824.   THEN
  825.     FOR i := 0 TO MagicAES.AESGlobal.apCount - 1 DO
  826.       apName[0] := '?';
  827.       apName[1] := 0C;
  828.       apName[2] := CHR(i);
  829.       apName[3] := 0C;
  830.       apId := MagicAES.ApplFind (ADR(apName));
  831.       IF (apId # 0) & (apId # mtAppl.ApplIdent)
  832.       THEN 
  833.         MagicAES.ApplWrite(apId, 16, access^);
  834.       END;
  835.     END;
  836.   END;
  837. END SeProtoInit;
  838.  
  839. PROCEDURE SEProtoActiv (): BOOLEAN;
  840. (* Gibt zurck, ob das SE-Protokoll aktiv ist
  841.  *)
  842. BEGIN
  843.   RETURN seCount >= 1;
  844. END SEProtoActiv;
  845.  
  846. PROCEDURE FindAVServer (VAR id: INTEGER): BOOLEAN;
  847.   CONST cAVServer = "AVSERVER=";
  848.   VAR avServer : ARRAY [0..79] OF CHAR;
  849.       i        : INTEGER;
  850.       apType   : INTEGER;
  851. BEGIN
  852.   FOR i := 0 TO 79 DO avServer[i] := 0C; END;
  853.   id := -1;
  854.   IF mtCommand.EnvVar (cAVServer, avServer)
  855.   THEN
  856.     FOR i := 0 TO 7 DO 
  857.       IF avServer[i] = 0C
  858.       THEN
  859.         avServer[i] := ' ';
  860.       END;
  861.     END;
  862.     avServer[8] := 0C;
  863.     id := MagicAES.ApplFind (ADR(avServer));
  864.   END;
  865.   IF id < 0
  866.   THEN
  867.     (* Nach Applikation AVSERVER suchen *)
  868.     MagicStrings.Assign (cAVServer, avServer);
  869.     avServer[8] := 0C;
  870.     id := MagicAES.ApplFind (ADR(avServer));
  871.   END;
  872.   IF id < 0
  873.   THEN
  874.     (* Shell mit appl_search suchen *)
  875.     IF multiTOS OR (magIx & (magIxVer >= $200))
  876.     THEN
  877.       IF MagicAES.ApplSearch (MagicAES.APSHELL, avServer, apType, id)
  878.       THEN
  879.         IF apType # MagicAES.APTAPP
  880.         THEN
  881.           id := -1;
  882.         END;
  883.       END;
  884.     END;
  885.   END;
  886.   RETURN id >= 0;
  887. END FindAVServer;
  888.  
  889. PROCEDURE SendPathUpdate (REF path: ARRAY OF CHAR);
  890. (* Schickt ein AV_PATH_UPDATE an den AV_SERVER *)
  891.   VAR mess : POINTER TO RECORD
  892.                messId : INTEGER;
  893.                apId   : INTEGER;
  894.                over   : INTEGER;
  895.                fPath              : ADDRESS;
  896.                fName              : ADDRESS;
  897.                e15                : INTEGER;
  898.              END;
  899.      avId : INTEGER;
  900. BEGIN
  901.   IF ~FindAVServer (avId)
  902.   THEN
  903.     (* Wir schicken das an ID 0 *)
  904.     avId := 0;
  905.   END;
  906.   (* Wir schicken nichts an uns selbst *)
  907.   IF (avId = mtAppl.ApplIdent) THEN RETURN END;
  908.   mess := ADR (messBuff);
  909.   MagicStrings.Assign (FileNames.FilePath(path), memPtr^.mPath);
  910.   WITH mess^ DO
  911.     messId := AV_PATH_UPDATE;
  912.     apId   := mtAppl.ApplIdent;
  913.     over   := 0;
  914.     fPath  := ADR (memPtr^.mPath);
  915.     fName  := NIL;
  916.     e15    := 0;
  917.   END;
  918.   MagicAES.ApplWrite(avId, 16, mess^);
  919. END SendPathUpdate;
  920.  
  921. VAR hasMxAlloc  : BOOLEAN;
  922.     i           : CARDINAL;
  923.     tPtr        : Str255Ptr;
  924.  
  925. BEGIN
  926.   accCount := 1;
  927.   seCount  := 0;
  928.   hasMxAlloc := MagicDOS.Mxalloc ($FFFFFFFF,3) # ADDRESS(-32L);
  929.   IF multiTask & hasMxAlloc
  930.   THEN
  931.     (* Mxalloc: Readable, TT-RAM preferred *)
  932.     memPtr := MagicDOS.Mxalloc (TSIZE (memDescr), $43);
  933.   ELSE
  934.     ALLOCATE (memPtr, TSIZE (memDescr));
  935.   END;
  936.   IF memPtr = NIL THEN HALT END;
  937.   tPtr := CADR (appName);
  938.   FOR i := 0 TO 49 DO
  939.     memPtr^.apName[i]   := tPtr^[i];
  940.   END;
  941. END FredProtokoll.
  942.